/* 
 * Copyright (C) 2012 Martin Řehánek <Martin.Rehanek at mzk.cz>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

goog.provide('kramerius.audio.AudioPlayer');

goog.require('goog.debug.Logger');

/**
 * @constructor 
 * @param {kramerius.audio.Controller} controller
 * @param {boolean} loggingEnabled whether logging should be enabled (for debugging)
 */
kramerius.audio.AudioPlayer = function(controller, loggingEnabled, swfUrl){
    this.controller_ = controller;
    this.loggingEnabled_ = loggingEnabled;
    this.log_("initializing");
    this.ready_ = false;
    /** @private */
    this.nowPlaying_ = undefined;
    soundManager.setup(
    {   
        // where to find flash SWFs, as needed
        url: swfUrl
        //useHTML5Audio: 'true',
        ,
        debugMode: true
        //consoleOnly: true
        ,
        debugFlash: false
        //,html5Test: 'probably'
        ,
        preferFlash: 'true'
    //TODO
    //useFlashBlock: false, 
    //TODO: mozna
    //waitForWindowLoad: false
        
    });
    var player = this;
    soundManager.onready(function() {
        player.setReady_(true);
    });
};

/** @private */
kramerius.audio.AudioPlayer.prototype.setReady_ = function(ready){
    this.ready_ = ready;
}

kramerius.audio.AudioPlayer.prototype.isReady = function(){
    return this.ready_;
}


/**
 * Sets track to be played. Already playing track is released.
 * @param {kramerius.audio.Track} track
 * @param {Boolean} playNow If the track should be played right away
 */
kramerius.audio.AudioPlayer.prototype.setTrack = function(track, playNow){
    //    if (!this.isReady()){
    //        this.log_("setTrack: audio player not ready yet");
    //    }else{
    var audioPlayer = this;
    var controller = this.controller_;
    soundManager.onready(function() {
        var nowPlaying = audioPlayer.nowPlaying_;
        if (nowPlaying != undefined){
            nowPlaying.destruct();
        }
        if (track == null){
            audioPlayer.log_("track is empty");
            controller.setControllerState('empty');
        }else{
            audioPlayer.log_("track to be played: ");
            console.log(track);
            audioPlayer.log_("available urls: " + track.urlArray());
            audioPlayer.nowPlaying_ = soundManager.createSound({
                id: track.getId(),
                url: track.urlArray(),
                //                autoLoad: true,
                autoPlay: playNow,
                stream: true,
                multiShot: false,
                multiShotEvents: true,
                //                usePolicyFile:false,
                onbufferchange: function(){
                    audioPlayer.log_("onbufferchange");
                },
                onconnect: function(){
                    audioPlayer.log_("onconnect");
                },
                ondataerror: function(){
                    audioPlayer.log_("ERROR: error reading audio data");
                    controller.setControllerState('empty');
                },
                onfinish: function(){
                    audioPlayer.log_("onfinish");
                    if (controller.canPlayNextTrack()){
                        controller.playNextTrack();
                        audioPlayer.log_("playing next track in playlist");
                    }else{
                        audioPlayer.log_("finished playing last track in playlist");
                        controller.setControllerState('paused');
                    }
                },
                onload: function(success){
                    audioPlayer.log_("onload");
                    if (success){
                        audioPlayer.log_("successfully loaded");
                        if(playNow){
                            controller.setControllerState('playing');    
                        }
                    }else{
                        audioPlayer.log_("failed to load or loaded from cache");
                    }
                },
                onpause: function(){
                    audioPlayer.log_("onpause");
                    controller.setControllerState('paused');
                },
                onplay: function(){
                    audioPlayer.log_("onplay");
                    controller.activateSelectedTrackIfNoActive();
                    if (this.loaded){//i.e. playing again after being stopped
                        controller.setControllerState('playing');
                    }
                },
                onresume: function(){
                    audioPlayer.log_("onresume");
                    controller.setControllerState('playing');
                },
                onsuspend: function(){
                    audioPlayer.log_("onsuspend");
                },
                onstop: function(){
                    //TODO: tady se to chyta i kdyz zavolam empty
                    audioPlayer.log_("onstop");
                    controller.setControllerState('stopped');
                },
                onid3: function(){
                    //TODO: ma to smysl? budou mit alespon MP3 id3?
                    audioPlayer.log_("id3 data recieved");
                //console.log("id3: ");
                //console.log(this.id3);
                },
                whileloading: function(){
                    controller.setTotalLength(this.durationEstimate);
                },
                whileplaying: function(){
                    //audioPlayer.log_("setting position to " + this.position);
                    controller.setPosition(this.position);
                }
            });
            
            //audioPlayer.nowPlaying_.play();
            audioPlayer.nowPlaying_.load();
        }
    });
//}
};


kramerius.audio.AudioPlayer.prototype.play = function(){
    if (this.nowPlaying_ != undefined){
        this.log_("playing " + this.nowPlaying_.id);
        this.nowPlaying_.play();
    } else {
        //var logger = new goog.debug.Logger("audioPlayer");
        //logger.severe("nowPlaying is not defined");
        this.log_("nowPlaying is not defined");
    }
}


kramerius.audio.AudioPlayer.prototype.pause = function(){
    this.log_("pausing " + this.nowPlaying_.id);
    this.nowPlaying_.pause();
}


kramerius.audio.AudioPlayer.prototype.stop = function(){
    if (this.nowPlaying_ != undefined){
        this.log_("stopping " + this.nowPlaying_.id);
        this.nowPlaying_.stop();
    }
}


kramerius.audio.AudioPlayer.prototype.resume = function(){
    this.log_("resuming " + this.nowPlaying_.id);
    this.nowPlaying_.resume();
}


kramerius.audio.AudioPlayer.prototype.isPaused = function(){
    var result = (this.nowPlaying_ != undefined && this.nowPlaying_.paused);
    this.log_('isPaused: ' + result);
    return result;
}


kramerius.audio.AudioPlayer.prototype.isPlayingOrBuffering = function(){
    var result = (this.nowPlaying_ != undefined 
        && this.nowPlaying_.playState == 1);
    this.log_('isPlayingOrBuffering: ' + result);
    return result;
}


kramerius.audio.AudioPlayer.prototype.isStoppedOrUninitialized = function(){
    var result = (this.nowPlaying_ != undefined 
        && this.nowPlaying_.playState == 0);
    this.log_('isStoppedOrUninitialized: ' + result);
    return result;
}


kramerius.audio.AudioPlayer.prototype.setVolume = function(volumeLevel){
    if (this.nowPlaying_ != undefined){
        this.nowPlaying_.setVolume(volumeLevel);
    // console.log("AudioPlayer: updating volume level to " + volumeLevel);
    }
}


kramerius.audio.AudioPlayer.prototype.setPosition = function(position){
    if (this.nowPlaying_ != undefined){
        if(kramerius.audio.utils.differsByAtLeast(this.nowPlaying_.position, position, 100)){
            this.nowPlaying_.setPosition(position);
            console.log("AudioPlayer: updating position");
        } else{
        //TODO: odstranit
        //this.log_("setPosition: change of position too small");  
        }
    }
    else {
        this.log_("setPosition: nowPlaying_ not defined");
    }
}

kramerius.audio.AudioPlayer.prototype.log_ = function(text){
    if (this.loggingEnabled_){
        console.log("AudioPlayer: " + text);
    }
}

